#define _GNU_SOURCE 1

#include <stdio.h>
#include <sched.h>
#include <pthread.h>
#include <mqueue.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <unistd.h>

#define THREAD_PRIORITY_SHOW() \
	int policy; \
	struct sched_param sp; \
    sched_getparam(0, &sp); \
    printf("\n%d\n", sp.sched_priority); \
	pthread_getschedparam(pthread_self(), &policy, &sp); \
	printf("policy: %d, priority: %d\n", policy, sp.sched_priority);


void* Pthread(void);
void* Pthread1(void);
void* Pthread2(void);

mqd_t mq;

void no_mq_create(mqd_t* mq, const char* name, long length, long msgsize)
{
	struct mq_attr attr = {0};

	attr.mq_maxmsg = length;
	attr.mq_msgsize = msgsize;

	*mq = mq_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr);
	if (*mq == (mqd_t)-1) {
		printf("mq create error\n");
	}
	
}

int a[10000];
int count;


int main(int argn, char* argc[])
{
    int ret, status;
    pthread_t p[5] = {0};
    void* (*thread_array[5])(void) = {Pthread1, Pthread2, Pthread, Pthread, Pthread};
    struct mq_attr attr = {0};
    char name[] = "/12345";

    count = 0;
    

    // attr.mq_maxmsg = 2;
    // attr.mq_msgsize = 50;

    // mq = mq_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr);
    no_mq_create(&mq, name, 2, 50);
    
    for (int i = 0; i < 2; i++)
    {
        a[count++] = 0;
        ret = pthread_create(&p[i], NULL, thread_array[i], NULL);
        a[count++] = 0;
    }

    for (int i = 0; i < 2; i++)
    {
        pthread_join(p[i], NULL);
    }

    printf("\n");
    for (int i = 0; i < count; i++)
    {
        printf("%d", a[i]);
    }
    printf("\n");
    
    return 0;

}

void* Pthread1(void)
{
    int ret;
    char msgrcd[50] = {0};
    THREAD_PRIORITY_SHOW()
    a[count++] = 1;
    ret = mq_receive(mq, msgrcd, sizeof(msgrcd), NULL);
    if (ret == -1){
        printf("receive %d error! errno: %d\n", ret,errno);
        return NULL;
    }
    a[count++] = 1;

    for (int i = 0; i < 99; i++)
    {
        a[count++] = 1;
        ret = mq_receive(mq, msgrcd, sizeof(msgrcd), NULL);
        if (ret == -1){
            printf("receive %d error! errno: %d\n", ret,errno);
            return NULL;
        }
        a[count++] = 1;
    }
    
    printf("%s\n", msgrcd);
}

void* Pthread2(void)
{
    int ret;
    char *msgsed = "12345";
    THREAD_PRIORITY_SHOW()
    for (int i = 0; i < 100; i++)
    {
        a[count++] = 2;
        ret = mq_send(mq, msgsed, strlen(msgsed), NULL);
        if (ret != 0){
            printf("send error! errno: %d\n", errno);
            return NULL;
        }
        a[count++] = 2;
    }
    
}

void* Pthread(void)
{
    THREAD_PRIORITY_SHOW()
}